import pandas as pd
from datetime import datetime, date, timedelta
from app.models import DetectionEvent, StreetStats
from app.extensions import db
from app.config import Config


def get_detection_data(start_date=None, end_date=None):
    """
    从数据库获取垃圾检测事件数据
    :param start_date: 开始日期
    :param end_date: 结束日期
    :return: 包含经纬度和垃圾类型的DataFrame
    """
    # 构建查询
    query = DetectionEvent.query.filter(DetectionEvent.lat.isnot(None), DetectionEvent.lng.isnot(None))

    # 添加日期过滤条件
    if start_date:
        query = query.filter(DetectionEvent.detect_time >= start_date)
    if end_date:
        # 包含end_date当天的所有数据
        end_date_plus_one = end_date + timedelta(days=1)
        query = query.filter(DetectionEvent.detect_time < end_date_plus_one)

    # 执行查询
    results = query.all()

    # 转换为DataFrame
    data = {
        'lat': [event.lat for event in results],
        'lng': [event.lng for event in results],
        'class': [event.class_ for event in results],
        'conf': [event.conf for event in results],
        'detect_time': [event.detect_time for event in results],
        'street_name': [event.street_name or '未知街道' for event in results]
    }

    return pd.DataFrame(data)


def get_street_stats(date_param=None):
    """
    获取指定日期的街道统计数据
    :param date_param: 日期
    :return: 街道统计数据的DataFrame
    """
    if not date_param:
        date_param = date.today() - timedelta(days=1)  # 默认获取昨天的数据

    # 从数据库获取统计数据
    stats = StreetStats.query.filter(StreetStats.date == date_param).all()

    # 转换为DataFrame
    data = {
        'street_name': [s.street_name for s in stats],
        'total_count': [s.total_count for s in stats],
        'top_class': [s.top_class for s in stats]
    }

    return pd.DataFrame(data)


def get_detection_stats(start_date=None, end_date=None):
    """
    获取指定时间范围的垃圾检测统计信息
    :param start_date: 开始日期
    :param end_date: 结束日期
    :return: 包含统计信息的字典
    """
    # 获取数据
    df = get_detection_data(start_date, end_date)

    if df.empty:
        return {
            'total_count': 0,
            'class_counts': {},
            'street_counts': {},
            'date_range': {'start': start_date, 'end': end_date}
        }

    # 计算统计信息
    total_count = len(df)
    class_counts = df['class'].value_counts().to_dict()
    
    # 按街道统计
    street_counts = df.groupby('street_name').agg({
        'class': 'count',
        'conf': 'mean'
    }).reset_index()
    street_counts.columns = ['street_name', 'count', 'avg_confidence']
    
    # 转换为字典形式
    street_data = []
    for _, row in street_counts.iterrows():
        street_data.append({
            'street_name': row['street_name'],
            'count': row['count'],
            'avg_confidence': row['avg_confidence']
        })
    
    return {
        'total_count': total_count,
        'class_counts': class_counts,
        'street_data': street_data,
        'date_range': {'start': start_date, 'end': end_date}
    }


# 以下是数据服务函数，可用于API集成
def get_detection_events_as_json(start_date=None, end_date=None):
    """
    获取检测事件数据并转换为JSON格式
    :param start_date: 开始日期
    :param end_date: 结束日期
    :return: JSON格式的检测事件数据
    """
    df = get_detection_data(start_date, end_date)
    # 转换为字典列表，便于JSON序列化
    return df.to_dict(orient='records')


# 示例：在Flask路由中使用这些函数
# @app.route('/api/detections', methods=['GET'])
# def api_detections():
#     start_date_str = request.args.get('start_date')
#     end_date_str = request.args.get('end_date')
#     
#     try:
#         start_date = datetime.strptime(start_date_str, '%Y-%m-%d').date() if start_date_str else None
#         end_date = datetime.strptime(end_date_str, '%Y-%m-%d').date() if end_date_str else None
#     except ValueError:
#         return jsonify({'error': '日期格式错误，请使用YYYY-MM-DD格式'}), 400
#     
#     return jsonify(get_detection_events_as_json(start_date, end_date))